/**
 ******************************************************************************
 * @file	shell 环境发起短连接
 * @brief	TODO:brief

TODO:introduce
 *
 @section Platform
	-#
 @section Library
	-#
- 20xx-xx-xx,author,email
 	- brief

 * @attention
 *
 * ATTENTION
 *
 * <h2><center>&copy; COPYRIGHT </center></h2>
*/


#include "epollserver.h"
#include <stdio.h>
#include <fcntl.h>
#include <getopt.h>


char *g_tcp = NULL;
char *g_port = NULL;
char *g_send = NULL;
int g_wait_recv = 0;
int g_timeout = 0;



int ConnectRemove()
{
	int fd;
	struct sockaddr_in remoteAddr;// 远端连接端口
	struct sockaddr_in locateAddr;// 绑定本地端口
	socklen_t len = sizeof(struct sockaddr_in);

	fd = socket(AF_INET, SOCK_STREAM, 0);

	// 连接后获取外部地址
	remoteAddr.sin_family      = AF_INET;
	remoteAddr.sin_addr.s_addr = inet_addr(g_tcp);
	remoteAddr.sin_port        = htons(atoi(g_port));
	if (connect(fd, (struct sockaddr *)&remoteAddr, sizeof(struct sockaddr_in)) != 0) {
		// TODO post message
		close(fd);
		return -1;
	}
	return fd;
}
int Unblock(int fd)
{
	int op;

	op = fcntl(fd, F_GETFL);
	if (fcntl(fd, F_SETFL, op | O_NONBLOCK) < 0) {
		perror("ep_Setnonblocking fctl error\n");

		return errno;
	}
}
int RecvAsciiTm(int fd, int timeout)
{
	int rbuf[64];
	int ret;
	int tm = 0;

	while(tm < timeout) {
		ret = recv(fd, rbuf, sizeof(rbuf), 0);
		switch(ret) {
		case 0:
			return -1;
		case -1:
			usleep(5000);
			tm += 5;
			continue;
		default:
			break;
		}
		rbuf[ret] = '\0';
		// printf("%s", rbuf);
		break;
		
	}
	return 0;
}

int RecvOne(int fd)
{
	int rbuf[64];
	int ret;

	while(1) {
		ret = recv(fd, rbuf, sizeof(rbuf), 0);
		switch(ret) {
		case 0:
			return -1;
		case -1:
			usleep(5000);
			continue;
		default:
			break;
		}
		rbuf[ret] = '\0';
		// printf("%s", rbuf);
		break;
	}
	return 0;
}



static void parse_opts(int argc, char *argv[])
{
	int ret;
	while (1) {
		static const struct option lopts[] = {
			{ "tcp",  1, 0, 't' },
			{ "port",   1, 0, 'p' },
			{ "time",   1, 0, 'T' },
			{ "send",     1, 0, 's' },
			{ "recv",   0, 0, 'r' },
			{ NULL, 0, 0, 0 },
		};
		int c;

		c = getopt_long(argc, argv, "t:p:T:s:r", lopts, NULL);
		if (c == -1) {
			break;
		}

		switch (c) {
		case 't':
			g_tcp = optarg;
			break;
		case 'p':
			g_port = optarg;
			break;
		case 'T':
			g_timeout = atoi(optarg)*1000;
			break;
		case 's':
			g_send = optarg;
			break;
		case 'r':
			g_wait_recv = 1;
			break;
		default:

			break;
		}

	}
}
int main(int argc, char const *argv[])
{
	int fd;

	parse_opts(argc, argv);
	fd = ConnectRemove();
	send(fd, g_send, strlen(g_send), 0);

	if (g_wait_recv) {
		Unblock(fd);
		if (g_timeout) {
			RecvAsciiTm(fd, g_timeout);
		}
		else {
			RecvOne(fd);	
		}
		
	}
	close(fd);
	return 0;
}